package eu.sudparis.it.opp.format.pagerank;

import java.util.*;
import Jama.Matrix;


public class Ranking {

	private final double DAMPING_FACTOR = 0.85;

	private List<String> params = new ArrayList<String>();
	private HashMap<String,String[]> inLinks=new HashMap<String,String[]>();
	private HashMap<String,String[]> outLinks=new HashMap<String,String[]>();
	
	public static void main(String[] args) {

		Ranking ranking = new Ranking();

		System.out.print(ranking.rank("C"));

	}


	public double rank(String pageId) {

		generateParamList(pageId);

		Matrix a = new Matrix(generateMatrix());

		double[][] arrB = new double[params.size()][1];

		for (int i = 0; i < params.size(); i++) {

			arrB[i][0] = 1 - DAMPING_FACTOR;

		}

		Matrix b = new Matrix(arrB);
		Matrix x = a.solve(b);

		int ind = 0;

		int cnt = 0;

		for (Iterator<String> it = params.iterator(); it.hasNext();) {

			String curPage = (String) it.next();

			if (curPage.equals(pageId))

				ind = cnt;

			cnt++;

		}

		return x.getArray()[ind][0];

	}

	private double[][] generateMatrix() {
		double[][] arr = new double[params.size()][params.size()];
		for (int i = 0; i < params.size(); i++) {
			for (int j = 0; j < params.size(); j++) {
				arr[i][j] = getMultiFactor((String) params.get(i),(String) params.get(j));
			}
		}
		return arr;
	}

	private double getMultiFactor(String sourceId, String linkId) {
		if (sourceId.equals(linkId))
			return 1;
		else {
			String[] inc = getInboundLinks(sourceId);
			for (int i = 0; i < inc.length; i++) {
				if (inc[i].equals(linkId)) {
					return -1* (DAMPING_FACTOR / getOutboundLinks(linkId).length);
				}
			}
		}
		return 0;
	}

	/*
	 * 
	 * This method returns list of the related pages. This list is also the
	 * 
	 * parameters in the linear equation.
	 */

	private void generateParamList(String pageId) {
		if (!params.contains(pageId))
			params.add(pageId);
		String[] inc = getInboundLinks(pageId);

		for (int i = 0; i < inc.length; i++) {
			if (!params.contains(inc[i]))
				generateParamList(inc[i]);
		}
	}

	/*
	 * 
	 * Return list of the inbound links to a given page.
	 */

	private String[] getInboundLinks(String pageId) {
		return inLinks.get(pageId);
	}

	/*
	 * 
	 * Returns list of the outbound links from a page.
	 */

	private String[] getOutboundLinks(String pageId) {
		return outLinks.get(pageId);
	}

}
